﻿using System;
using BattleNet.DataAccess.Parsers.Exceptions;
using BattleNet.DataAccess.Parsers.Html;
using BattleNet.DataAccess.SourceProviders.Interface;
using BattleNet.Entities;
using BattleNet.Entities.Enums;
using Xunit;

namespace BattleNet.DataAccess.UnitTests.Parsers.Html
{
    public class HtmlRealmParserTest
    {
        
        [Fact]
        public void Parse_NoRealmFound_ThrowsRealmNotFoundException()
        {
            var source = new TestSourceProvider("existingRealmName");
            HtmlRealmFinder parser = new HtmlRealmFinder(source);
            Assert.Throws<RealmNotFoundException>(() => parser.Find("nonExistingRealmName"));
        }

        [Fact]
        public void Parse_FindNullProvided_ThrowsArgumentNullException()
        {
            var source = new TestSourceProvider("realmName");
            HtmlRealmFinder parser= new HtmlRealmFinder(source);
            Assert.Throws<ArgumentNullException>(() => parser.Find(null));
        }

        [Fact]
        public void Parse_NoSourceProvoded_ThrowsArgumentNullException()
        {
            Assert.Throws <ArgumentNullException>(() => new HtmlRealmFinder(null));
        }


        [Fact]
        public void Parse_FoundRealmBadHtml_ThrowsHtmlParsingInformation()
        {
            var source = new FalseSourceProvider();
            string realmName = "Kilrogg";
            HtmlRealmFinder parser = new HtmlRealmFinder(source);
            Assert.Throws<HtmlParsingException>(() => parser.Find(realmName));
        }

        [Fact]
        public void Parse_RealmFound_ProvidedHtmlIsAsExpected_ReturnsCorrectRealmClass()
        {
            var source = new TestSourceProvider("realmName");
            Realm expectedRealm = DemoRealmCreater("realmName");

            HtmlRealmFinder parser = new HtmlRealmFinder(source);
            Realm actualRealm = parser.Find("realmName");
            Assert.Equal(expectedRealm,actualRealm);
        }

        private Realm DemoRealmCreater(string realmName)
        {
            return DemoRealmCreater(RealmStatus.Up, "realmName", RealmType.PvE, PopulationStatus.Medium, "locale", false);
        }
        private Realm DemoRealmCreater(RealmStatus status,string realmName,RealmType type, PopulationStatus populationStatus, string locale, bool queue)
        {
            return new Realm
                       {
                           Locale = locale,
                           Name = realmName,
                           Population = populationStatus,
                           Queue = queue,
                           Status = status,
                           Type = type
                       };
        }
        
    }

    public class TestSourceProvider : ISourceProvider<string>
    {
        private RealmStatus _status;
        private string _realmName;
        private RealmType _realmType;
        private PopulationStatus _population;
        private string _locale;
        private bool _queue;


        public TestSourceProvider(RealmStatus status, string realmName, RealmType realmType, PopulationStatus popstatus, string locale, bool queue)
        {
            this._status = status;
            this._realmName = realmName;
            this._realmType = realmType;
            this._population = popstatus;
            this._locale = locale;
            this._queue = queue;
        }
        public TestSourceProvider(string realmName) : this(RealmStatus.Up,realmName,RealmType.PvE,PopulationStatus.Medium,"locale",false)
        {
            
        }
        public string Provide()
        {
            return String.Format(
                "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
                + "<head> </head>"
                + "<body>"
                + "<div id=\"all-realms\" style=\"display:none\">"
                + "<div class=\"table full width\">"
                + "<table>"
                + "<thead>"
                + "<tr>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Status</span></a></th>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Realm Name</span></a></th>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Type</span></a></th>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Population</span></a></th>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Locale</span></a></th>"
                + "<th><a href=\"javascript:;\" class=\"sort-link\"><span class=\"arrow\">Queue</span></a></th>"
                + "</tr>"
                + "</thead>"
                + "<tbody>"
                + "<tr class=\"row1\" style=\"display: table-row; \">"
                + "<td class=\"status\" data-raw=\"{0}\">"
                + "<div class=\"status-icon up\" onmouseover=\"Tooltip.show(this, 'Up')\"></div>"
                + "</td>"
                + "<td class=\"name\">{1}</td>"
                + "<td class=\"type\" data-raw=\"{2}\">"
                + "<span class=\"pvp\">({2})</span>"
                + "</td>"
                + "<td class=\"population\" data-raw=\"{3}\">"
                + "<span class=\"low\">{3}</span>"
                + "</td>"
                + "<td class=\"locale\">{4}</td>"
                + "<td class=\"queue\" data-raw=\"{5}\"></td>"
                + "</tr>"
                + "</tbody>"
                + "</table>"
                + "</div>"
                + "</div>"
                + "</body>"
                + "</html>"
                , _status, _realmName, _realmType, _population, _locale, _queue);
        }
    }

    public class FalseSourceProvider : ISourceProvider<string>
    {

        public string Provide()
        {
            return "False source provided";
        }
    }
}
